package com.lyncs.ods.modules.company.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lyncs.ods.constant.LyncsOdsConstant;
import com.lyncs.ods.modules.company.mapper.CompanyUserRoleMapper;
import com.lyncs.ods.modules.company.model.CompanyUserRole;
import com.lyncs.ods.modules.company.service.CompanyRelationRoleService;
import com.lyncs.ods.modules.company.service.CompanyUserRoleService;
import com.lyncs.ods.resp.CompanyGroupInfo;
import com.lyncs.ods.resp.UserGroupInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 企业用户权限信息 服务实现类
 * </p>
 *
 * @author alex
 * @since 2022-07-11
 */
@Service
public class CompanyUserRoleServiceImpl extends ServiceImpl<CompanyUserRoleMapper, CompanyUserRole> implements CompanyUserRoleService {

    @Autowired
    private CompanyRelationRoleService companyRelationRoleService;

    @Override
    public List<Long> getUserGroupRoleIds(@NotNull Long companyId, @NotNull Long userId) {
        List<CompanyUserRole> roles = lambdaQuery().eq(CompanyUserRole::getCompanyId, companyId)
                .eq(CompanyUserRole::getUserId, userId)
                .eq(CompanyUserRole::getStatus, LyncsOdsConstant.EnableStatus.ENABLE.getKey())
                .list();
        return CollectionUtils.isEmpty(roles) ? List.of() : roles.stream().map(CompanyUserRole::getGroupId).distinct().collect(Collectors.toList());
    }

    @Override
    public Map<Long, List<Long>> getUserGroupRoleIds(@NotNull Long companyId, @NotNull List<Long> userIds) {
        List<CompanyUserRole> roles = lambdaQuery().eq(CompanyUserRole::getCompanyId, companyId)
                .in(CompanyUserRole::getUserId, userIds)
                .eq(CompanyUserRole::getStatus, LyncsOdsConstant.EnableStatus.ENABLE.getKey())
                .list();
        return CollectionUtils.isEmpty(roles) ? Map.of() : roles.stream().collect(Collectors.groupingBy(CompanyUserRole::getGroupId, Collectors.mapping(CompanyUserRole::getGroupId, Collectors.toList())));
    }

    @Override
    public Map<Long, List<UserGroupInfo>> getUserGroupInfos(@NotNull Long companyId, @NotNull List<Long> userIds) {
        Map<Long, List<UserGroupInfo>> userMap = new HashMap<>();
        Map<Long, List<Long>> map = getUserGroupRoleIds(companyId, userIds);
        if (MapUtils.isEmpty(map)) {
            return userMap;
        }
        List<Long> groupIds = map.values().stream().flatMap(Collection::stream).distinct().collect(Collectors.toList());
        List<CompanyGroupInfo> groupCompanyInfos = companyRelationRoleService.getGroupCompanyInfos(companyId, groupIds);
        Map<Long, String> groupNameMap = groupCompanyInfos.stream().collect(Collectors.toMap(CompanyGroupInfo::getGroupId, CompanyGroupInfo::getGroupName, (o1, o2) -> o1));
        Map<Long, Map<Long, String>> groupRelationNameMap = groupCompanyInfos.stream().collect(Collectors.groupingBy(CompanyGroupInfo::getGroupId, Collectors.toMap(CompanyGroupInfo::getRelationId, CompanyGroupInfo::getNickname, (o1, o2) -> o1)));
        map.forEach((userId, ids) -> {
            List<UserGroupInfo> userGroupInfos = ids.stream().map(groupId -> {
                Map<Long, String> thisMap = groupRelationNameMap.getOrDefault(groupId, null);
                if (MapUtils.isEmpty(thisMap)) {
                    return null;
                }
                UserGroupInfo userGroupInfo = new UserGroupInfo();
                userGroupInfo.setUserId(userId)
                        .setGroupId(groupId)
                        .setGroupName(groupNameMap.getOrDefault(groupId, null))
                        .setCompanyInfos(thisMap.entrySet().stream().map(e -> new UserGroupInfo.GroupCompanyInfo().setRelationId(e.getKey()).setNickName(e.getValue())).collect(Collectors.toList()));
//                userMap.put(userId, userGroupInfo);
                return userGroupInfo;
            }).collect(Collectors.toList());
            userMap.put(userId, userGroupInfos);
        });
        return userMap;
    }

    @Override
    public List<Long> listAllAvailablePartnerId(Long userId, Long companyId) {
        return this.baseMapper.listAllAvailablePartnerId(userId, companyId);
    }
}
